package com.ruoyi.system.basicInformation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.exception.CustomException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.ruoyi.system.basicInformation.bo.TElectronicFenceAddBo;
import com.ruoyi.system.basicInformation.bo.TElectronicFenceQueryBo;
import com.ruoyi.system.basicInformation.bo.TElectronicFenceEditBo;
import com.ruoyi.system.basicInformation.domain.TElectronicFence;
import com.ruoyi.system.basicInformation.mapper.TElectronicFenceMapper;
import com.ruoyi.system.basicInformation.vo.TElectronicFenceVo;
import com.ruoyi.system.basicInformation.service.ITElectronicFenceService;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 电子围栏Service业务层处理
 *
 * @author ruoyi
 * @date 2021-05-20
 */
@Service
public class TElectronicFenceServiceImpl extends ServiceImpl<TElectronicFenceMapper, TElectronicFence> implements ITElectronicFenceService {

    @Autowired
    TElectronicFenceMapper tElectronicFenceMapper;

    @Override
    public TElectronicFenceVo queryById(Long id) {
        TElectronicFence db = tElectronicFenceMapper.selectByIdForGeom(id);
        return BeanUtil.toBean(db, TElectronicFenceVo.class);
    }

    @Override
    public List<TElectronicFenceVo> queryList(TElectronicFenceQueryBo bo) {
//        LambdaQueryWrapper<TElectronicFence> lqw = Wrappers.lambdaQuery();
//        lqw.like(StrUtil.isNotBlank(bo.getName()), TElectronicFence::getName, bo.getName());
//        lqw.eq(StrUtil.isNotBlank(bo.getIsShow()), TElectronicFence::getIsShow, bo.getIsShow());
//        return entity2Vo(this.list(lqw));
        return baseMapper.selectListForGeom(bo);
    }

    @Override
    public String importUser(List<TElectronicFence> userList, Boolean isUpdateSupport, String operName) {
        if (Validator.isNull(userList) || userList.size() == 0) {
            throw new CustomException("电子围栏导入失败，原因是数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        //String password = configService.selectConfigByKey("sys.user.initPassword");
        for (TElectronicFence user : userList) {
            try {
                // 验证是否存在这个用户
                if ("是".equals(user.getIsShow().trim())) {
                    user.setIsShow("0");
                } else {
                    user.setIsShow("1");
                }
                TElectronicFence u = baseMapper.selectUserByName(user.getName());
                if (Validator.isNull(u)) {
                    user.setCreateBy(operName);
                    try {
                        this.insertShip(user);
                        successNum++;
                        successMsg.append("<br/>" + successNum + "、围栏名称 " + user.getName() + " 导入成功");
                    } catch (Exception e) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、围栏名称 '" + user.getName() + "' 导入失败，原因是数据不规范");
                    }
                } else if (isUpdateSupport) {
                    user.setUpdateBy(operName);
                    user.setId(u.getId());
                    try {
                        this.updateShip(user);
                        successNum++;
                        successMsg.append("<br/>" + successNum + "、围栏名称 " + user.getName() + " 更新成功");
                    } catch (Exception e) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、围栏名称 '" + user.getName() + "' 导入失败，原因是数据不规范");
                    }
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、围栏名称 " + user.getName() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、围栏名称 " + user.getName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new CustomException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 新增保存用户信息
     *
     * @param bo 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertShip(TElectronicFence bo) {
        TElectronicFence add = BeanUtil.toBean(bo, TElectronicFence.class);
        validEntityBeforeSave(add);
        tElectronicFenceMapper.insertByAddBoFortheGeom(add);
        return Integer.parseInt(add.getId().toString());
    }

    /**
     * 修改保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateShip(TElectronicFence user) {
        TElectronicFenceEditBo bo = new TElectronicFenceEditBo();
        bo.setId(user.getId().intValue());
        bo.setName(user.getName());
        bo.setIsShow("0".equals(user.getIsShow()) ? 0 : 1);
        bo.setMapRange(user.getMapRange());
        bo.setTheGeom(user.getTheGeom());
        bo.setUpdateBy(user.getUpdateBy());
        bo.setUpdateTime(new Date());
        return tElectronicFenceMapper.updateFenceForGeom(bo) > 0 ? 1 : 0;
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<TElectronicFenceVo> entity2Vo(Collection<TElectronicFence> collection) {
        List<TElectronicFenceVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, TElectronicFenceVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<TElectronicFence> page = (Page<TElectronicFence>) collection;
            Page<TElectronicFenceVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Integer insertByAddBo(TElectronicFenceAddBo bo) {
        TElectronicFence add = BeanUtil.toBean(bo, TElectronicFence.class);
        validEntityBeforeSave(add);
        tElectronicFenceMapper.insertByAddBoFortheGeom(add);
        return Integer.parseInt(add.getId().toString());
    }

    @Override
    public Boolean updateByEditBo(TElectronicFenceEditBo bo) {
        TElectronicFence update = BeanUtil.toBean(bo, TElectronicFence.class);
        validEntityBeforeSave(update);
        tElectronicFenceMapper.deleteFenceObject(bo.getId(), 1);
        tElectronicFenceMapper.deleteFenceObject(bo.getId(), 2);
        tElectronicFenceMapper.deleteFenceObject(bo.getId(), 3);
        return tElectronicFenceMapper.updateFenceForGeom(bo) > 0;
        // return this.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TElectronicFence entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
            for (Long id : ids) {
                tElectronicFenceMapper.deleteFenceObject(Integer.parseInt(id.toString()), 0);
            }
        }
        return this.removeByIds(ids);
    }

    /**
     * 判断坐标点是否在指定电子围栏里面
     *
     * @param lng     x坐标
     * @param lat     y坐标
     * @param fenceId 围栏主键
     * @return
     */
    @Override
    public Boolean checkIsExistsForXY(BigDecimal lng, BigDecimal lat, long fenceId) {
        String xy = "POINT(" + lng + " " + lat + ")";
        TElectronicFence db = tElectronicFenceMapper.checkIsExistsForXY(xy, fenceId);
        return db == null ? false : db.getId() > 0;
    }

    @Override
    public String checkNameUnique(String name, int id) {
        LambdaQueryWrapper<TElectronicFence> lqw = Wrappers.lambdaQuery();
        if (id != 0)
            lqw.notIn(TElectronicFence::getId, id);
        lqw.eq(TElectronicFence::getName, name);
        lqw.eq(TElectronicFence::getDelFlag, "0");
        lqw.last("limit 1");
        int count = count(lqw);
        if (count > 0) {
            return "1";
        }
        return "0";
    }
}
